package yxy.game.pm2.bean.area;

import java.util.ArrayList;
import java.util.Collection;

import org.redisson.api.RMap;

import yxy.apple.logger.Logger;
import yxy.apple.util.redisson.RedisConnection;
import yxy.apple.util.redisson.RedisException;
import yxy.banana.launcher.Launcher;
import yxy.cherry.game.base.redis.RedisManager;
import yxy.cherry.game.base.redis.RedisType;
import yxy.game.pm2.bean.ServerBean;
import yxy.game.pm2.bean.module.BaseGameRedisBean;

public class AreaBean extends BaseGameRedisBean {
	protected static Logger logger = Logger.create(AreaBean.class);
	// bean===========================================================================

	private int areaId;
	private int worldLevel;
	private ArrayList<String> serverList = new ArrayList<>();
	private boolean meraged;// 是否已被合并
	private int mergeTimes; //合服次数
	private int groupId; //所属跨服战区
	private int clusterId; //所属专服


	public int getAreaId() {
		return areaId;
	}

	public void setAreaId(int areaId) {
		this.areaId = areaId;
	}

	public int getWorldLevel() {
		return worldLevel;
	}

	public void setWorldLevel(int worldLevel) {
		this.worldLevel = worldLevel;
	}

	public ArrayList<String> getServerList() {
		return serverList;
	}

	public void setServerList(ArrayList<String> serverList) {
		this.serverList = serverList;
	}

	public boolean isMeraged() {
		return meraged;
	}

	public void setMeraged(boolean meraged) {
		this.meraged = meraged;
	}

	public int getMergeTimes() {
		return mergeTimes;
	}

	public void setMergeTimes(int mergeTimes) {
		this.mergeTimes = mergeTimes;
	}

	public int getGroupId() {
		return groupId;
	}

	public void setGroupId(int groupId) {
		this.groupId = groupId;
	}

	public int getClusterId() {
		return clusterId;
	}

	public void setClusterId(int clusterId) {
		this.clusterId = clusterId;
	}

	// func==========================================================================

	public void addServer(int serverId) {
		try {
			if (tryLock()) {
				ServerBean server = ServerBean.get(serverId);
				if (server == null) {
					return;
				}
				int oldareaId = server.getAreaId();
				if (oldareaId == getAreaId()) {
					return;
				}
				AreaBean oldArea = AreaBean.get(oldareaId);
				if (oldArea != null) {
					oldArea.removeServer(serverId);
				}
				server.setAreaId(getAreaId());
				server.set();
				String serverCode = String.valueOf(serverId);
				if (getServerList().contains(serverCode)) {
					return;
				}
				getServerList().add(serverCode);
				set();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			unlock();
		}
	}

	public void removeServer(int serverId) {
		try {
			if (tryLock()) {
				ServerBean server = ServerBean.get(serverId);
				if (server == null) {
					return;
				}
				int oldareaId = server.getAreaId();
				if (oldareaId == getAreaId()) {
					server.setAreaId(0);
					server.set();
				}
				String serverCode = String.valueOf(serverId);
				if (!getServerList().contains(serverCode)) {
					return;
				}
				getServerList().remove(String.valueOf(serverId));
				set();
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			unlock();
		}
	}

	// redis==========================================================================

	static public String key() {
		return String.format("AREA:MAP");
	}

	static private String areaKey(int areaId) {
		return String.format("area_%s", areaId);
	}

	static private RMap<String, AreaBean> touch() throws RedisException {
		RedisConnection redis = RedisManager.getInstance().getConnection(RedisType.REDIS_GAME);
		return RedisManager.client(redis).getMap(key());
	}

	static public Collection<AreaBean> all() {
		try {
			return touch().readAllValues();
		} catch (RedisException e) {
		}
		return new ArrayList<>();
	}

	static public AreaBean get(int areaId) {
		try {
			RMap<String, AreaBean> map = touch();
			AreaBean area = map.get(areaKey(areaId));
			return area;
		} catch (RedisException e) {
			e.printStackTrace();
			return null;
		}
	}

	/** 生成一个新区域 */
	static public AreaBean create(int areaId) throws RedisException {
		AreaBean area = new AreaBean();
		area.setAreaId(areaId);
		area.setWorldLevel(1);
		area.set();
		return area;
	}

	public void set() {
		try {
			RMap<String, AreaBean> map = touch();
			//TODO:监测“AREA:MAP”数据被重置问题
			//if (getClusterId() < 1) throw new Exception("clusterid = 0");
			map.put(areaKey(getAreaId()), this);
		} catch (Exception e) {
			logger.error("%s", e.getMessage());
			logger.error("%s", e);
			e.printStackTrace();
		}
	}

	@Override
	public String lockKey() {
		return String.format("lock:%s", key());
	}

}
